//
//  Model.m
//
//  Created by Molon on 13-10-25.
//  Copyright (c) 2013年 Molon. All rights reserved.
//

#import "Model.h"
#import "MLDataHelper.h"
#import "ModelArray.h"
#import "MLClassPropManager.h"
#import "NSDictionary+MLKit.h"
#import "MLKitDebug.h"
#import "MLJSON.h"
#import "NSObject+MLKitDAO.h"

@interface Model()

@end

@implementation Model

+ (instancetype)turnObject:(NSDictionary*)dict
{
    Model *model = [self new];
    
    //key需要全部小写
    dict = [dict dictionaryWithLowercaseKeys];
    
    //根据当前Model的元素名字和dict的key来对应赋值
    NSDictionary *propToTypes = [[MLClassPropManager manager] propToTypesOfClass:[self class] untilSuperClass:[Model class] ignoreUntilClass:YES];
    for (NSString *key in [propToTypes allKeys]) {
        if ([key hasPrefix:@"o_"]) { //o_开头的说明代表other，是不处理的
            continue;
        }
        
        id object = dict[[key lowercaseString]]; //dict的key全部为小写
        [model setValue:object forKey:key andKeyType:propToTypes[key]];
    }
    
    return model;
}

#pragma mark - description and copy
- (id)copyWithZone:(NSZone *)zone {
    id model = [[[self class] allocWithZone:zone] init];
    
    NSDictionary *propToTypes = [[MLClassPropManager manager]propToTypesOfClass:[self class] untilSuperClass:[Model class] ignoreUntilClass:YES];
    
    for (NSString *key in [propToTypes allKeys]) {
        id object = [self valueForKey:key];
        if (object) {
//            if ([object isKindOfClass:[Model class]]||[object isKindOfClass:[ModelArray class]]) {
            if ([object conformsToProtocol:@protocol(NSCopying)]) {
                [model setValue:[object copy] forKey:key];
            }else{
                [model setValue:object forKey:key];
            }
        }
    }
    
    return model;
}

- (NSString*)description
{
    NSDictionary *propToTypes = [[MLClassPropManager manager]propToTypesOfClass:[self class] untilSuperClass:[Model class] ignoreUntilClass:YES];
    return [NSString stringWithFormat:@"\nModel-->%@\n%@",NSStringFromClass([self class]),[self dictionaryWithValuesForKeys:[propToTypes allKeys]].description];
}

#pragma mark - json
- (NSDictionary*)convertedDictionaryWithIgnoreNil:(BOOL)ignoreNil
{
    //获取自己的属性，组成字典
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    
    //根据当前Model的元素名字和dict的key来对应赋值
    NSDictionary *propToTypes = [[MLClassPropManager manager]propToTypesOfClass:[self class] untilSuperClass:[Model class] ignoreUntilClass:YES];
    
    for (NSString *key in [propToTypes allKeys]) {
        if ([key hasPrefix:@"o_"]) { //o_开头的说明代表other，是不处理的
            continue;
        }
        
        id object = [self valueForKey:key];
        if (!object||[object isKindOfClass:[NSNull class]]) {
            if (ignoreNil) {
                continue;
            }
            dict[key] = [NSNull null];
            continue;
        }
        
        //检测是否是Model子类
        if ([object isKindOfClass:[Model class]]) {
            dict[key] = [object convertedDictionaryWithIgnoreNil:ignoreNil];
            continue;
        }
        //是否是ModelArray子类
        if ([object isKindOfClass:[ModelArray class]]) {
            dict[key] = [object convertedArrayWithIgnoreNil:ignoreNil];
            continue;
        }
        
        //是否是数组
        if ([object isKindOfClass:[NSArray class]]||[object isKindOfClass:[NSDictionary class]]) {
            NSAssert([object isValidJSONObject], @"%@的%@值不可转换为JSON",NSStringFromClass([self class]),key);
            dict[key] = object;
            continue;
        }
        
        //是否是NSURL
        if ([object isKindOfClass:[NSURL class]]) {
            dict[key] = [object absoluteString];
            continue;
        }
        
        //是否是其他支持的值
        if ([object isKindOfClass:[NSString class]]||[object isKindOfClass:[NSNumber class]]) {
            dict[key] = object;
            continue;
        }
        
        //其他的就不支持了
        NSAssert(NO, @"抱歉，只支持标量以及NSNumber,NSString,NSDictionary,NSArray,NSURL,Model子类,ModelArray子类");
    }
    
    return dict;
}


- (NSString *)JSONStringWithIgnoreNil:(BOOL)ignoreNil
{
    NSDictionary *dict = [self convertedDictionaryWithIgnoreNil:ignoreNil];
    NSAssert([dict isValidJSONObject], @"此Model不能转换为JSON，请检查");
    
    return [dict JSONString];
}

@end
